package com.hardson.toolkit.listcomparator;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.hardson.toolkit.util.MethodUtil;

public abstract class ListComparator<T> implements Comparator<T> {
	public static final int DATATYPE_STRING = 1;// 字符串类型

	public static final int DATATYPE_DOUBLE = 2;// 双精度浮点型

	public static final int DATATYPE_DATE = 3;// 日期类型

	public static final int DATATYPE_CHINESE = 4;// 中文字符串类型

	public static final int ORDER_ASC = 100;// 顺序

	public static final int ORDER_DESC = 101;// 倒序

	protected String colName = "";// 被比较的属性名称

	protected Class<?> cl = null;// 被比较的列表对象的类型

	protected int order = ORDER_ASC;// 顺序或倒序，默认为顺序

	/**
	 * 比较器的比较方法，在子类中实现
	 */
	@Override
	public abstract int compare(final T t0, final T t1);

	protected Integer compareNull(final Object val0, final Object val1) {
		if (val0 == null && val1 == null) {
			return 0;
		} else if (val0 == null) {
			return -1;
		} else if (val1 == null) {
			return 1;
		}
		return null;
	}

	/**
	 * 获取两个比较对象的指定属性(colName)的值
	 *
	 * @param obj1
	 *            要比较的一个对象
	 * @param obj2
	 *            要比较的另一个对象
	 * @return Object[]，被比较的两个对象中指定属性的值的数组
	 */
	protected Object getValueObj(final T obj) {
		if (obj == null) {
			return null;
		}
		try {
			String mName = MethodUtil.toMethodName(this.colName, "get");// 获得字段的获取方法
			Object val1 = MethodUtil.invoke(obj, mName);// 调用方法，得到对象的colName属性值
			return val1;// 返回对象
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 交换两个对象，用于控制升序或降序
	 *
	 * @param obj1
	 * @param obj2
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected T[] swap(T t1, T t2) {
		if (this.order == ORDER_DESC) {
			T oTmp = t1;
			t1 = t2;
			t2 = oTmp;
		}
		return (T[]) new Object[] { t1, t2 };
	}

	/**
	 * @return 排序方式（顺序/倒序）
	 */
	public final int getOrder() {
		return this.order;
	}

	/**
	 * @param 排序方式（顺序/倒序）
	 */
	public final void setOrder(final int order) {
		this.order = order;
	}

	/**
	 *
	 * The Class type is no longer needed.
	 *
	 * @return 列表包装类型
	 */
	@Deprecated
	public final Class<?> getCl() {
		return this.cl;
	}

	/**
	 * The Class type is no longer needed.
	 *
	 * @param 列表包装类型
	 */
	@Deprecated
	public final void setCl(final Class<?> cl) {
		this.cl = cl;
	}

	/**
	 * @return 排序字段
	 */
	public final String getColName() {
		return this.colName;
	}

	/**
	 * @param 排序字段
	 */
	public final void setColName(final String colName) {
		this.colName = colName;
	}

	/**
	 * @param dataType
	 * @return
	 */
	/*
	 * @Deprecated public static final ListComparator getListComparator(final
	 * int dataType) { return ListComparatorFactory.getListComparator(dataType);
	 * }
	 */

	/*
	 * @Deprecated public static final ListComparator getListComparator(final
	 * int dataType, final String colName, final Class<?> clazz) { return
	 * ListComparatorFactory.getListComparator(dataType, colName, clazz,
	 * ListComparator.ORDER_ASC); }
	 */

	public static final <T> ListComparator<T> getListComparator(final int dataType,
			final String colName) {
		return ListComparatorFactory.getListComparator(dataType, colName, ListComparator.ORDER_ASC);
	}

	/*
	 * @Deprecated public static final ListComparator getListComparator(final
	 * int dataType, final String colName, final Class<?> clazz, final int
	 * order) { return ListComparatorFactory.getListComparator(dataType,
	 * colName, clazz, order); }
	 */

	public static final <T> ListComparator<T> getListComparator(final int dataType,
			final String colName, final int order) {
		return ListComparatorFactory.getListComparator(dataType, colName, order);
	}

	public static final <T> void sort(final List<T> dataList, final Comparator<T> comparator) {
		Collections.sort(dataList, comparator);
	}

	@Override
	public String toString() {
		StringBuffer buf = new StringBuffer();
		buf.append("Column Name(colName):").append(this.colName).append(";");
		// buf.append("Class In List
		// Name(c1):").append(this.cl.getName()).append(";");
		buf.append("Order Type(order):").append(this.order).append(".");
		return buf.toString();
	}
}
